Refactor PLM to use the canonical Learning Mode analyzer - #760
Open
Richie Gomez (richiemsft) wants to merge 5 commits into
Open
Refactor PLM to use the canonical Learning Mode analyzer#760Richie Gomez (richiemsft) wants to merge 5 commits into
Richie Gomez (richiemsft) wants to merge 5 commits into
Conversation
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 52e48fee-23e1-4b05-803c-522812fcdda2
Forward audit workload exit codes, avoid policy previews from truncated analysis, and retain the legacy current-directory exclusion in the temporary adjusted-config adapter. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 52e48fee-23e1-4b05-803c-522812fcdda2
Richie Gomez (richiemsft)
force-pushed
the
refactor-plm-canonical-analyzer
branch
from
August 7, 2026 21:12
337fa51 to
a1bf155
Compare
Store newly added PLM files with repository-standard LF endings so whitespace validation reports the actual content cleanly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 52e48fee-23e1-4b05-803c-522812fcdda2
Richie Gomez (richiemsft)
marked this pull request as ready for review
August 7, 2026 21:14
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 14 changed files in this pull request and generated 1 comment.
Suppressed comments (2)
src/host/plm/src/analysis.rs:90
- This conversion no longer applies the legacy AppPath-based self-access filter. The downstream filter only compares against
bin_path, butwxc --auditinvokesplm stopwithout--bin-path(src/core/wxc/src/main.rs:1331), so it defaults to the plm executable directory and cannot identify the audited workload's executable. Self-open events that the removedaccess_failuredecoder dropped will therefore be persisted as unnecessary filesystem grants. Preserve this filtering in the canonical decoder before AppPath is discarded, or carry the needed metadata into this adapter.
events.push(LearningModeAccessEvent {
time_created: chrono::Utc::now(),
process_id: denial.pid,
thread_id: 0,
file_path: denial.resource.clone(),
access_mask,
});
src/host/plm/src/analysis.rs:70
- The removed parser rejected control characters and Windows wildcard characters before producing policy entries, but this adapter now checks only the drive prefix and current directory. The canonical analyzer accepts absolute paths without that filename validation, and
config::normalize_pathalso does not reject these characters, so a denial such asC:\data\*.txtcan now be persisted into an adjusted policy. Restore the legacy path-shape check before creating the access event.
if !is_local_drive_path(&denial.resource)
|| is_current_directory_path(&denial.resource, current_directory)
{
Normalize non-verbatim Win32 output aliases during collision checks and keep metadata-only READ_CONTROL denials from producing content-access grants. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 52e48fee-23e1-4b05-803c-522812fcdda2
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 15 changed files in this pull request and generated 1 comment.
Suppressed comments (2)
src/host/plm/src/analysis.rs:72
- These canonical file denials are promoted without the legacy
looks_like_valid_pathcheck, which rejected control characters and Win32 wildcard characters. An attempted path such asC:\foo*can therefore reachreadwritePaths/readonlyPaths, producing a policy entry that the old generator intentionally excluded. Retain that validation in the compatibility adapter.
events.push(LearningModeAccessEvent {
time_created: chrono::Utc::now(),
process_id: denial.pid,
thread_id: 0,
file_path: denial.resource.clone(),
access_mask,
src/host/plm/src/analysis.rs:69
- The compatibility adapter drops the legacy per-event self-access filter. The removed decoder compared each denied object with that event's application path, but
DeniedResourcecarries no application path andwxc's audit stop call does not pass--bin-path; consequently, accesses to the workload executable can now be promoted into the generated policy. Preserve enough event attribution to apply the old self-access exclusion before creating these compatibility events.
for denial in denials {
match denial.resource_type {
ResourceType::File => {
if !is_local_drive_path(&denial.resource)
|| is_current_directory_path(&denial.resource, current_directory)
Compare existing outputs by filesystem identity, fail closed when identity cannot be examined, normalize default-stream aliases, and preserve canonical workload self-access filtering. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 52e48fee-23e1-4b05-803c-522812fcdda2
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 16 changed files in this pull request and generated 1 comment.
Suppressed comments (1)
src/backends/learning_mode/windows/src/extractors.rs:226
- This self-access check drops different files that share the same volume-relative path. For example,
ObjectName = D:\Tools\app.exeandAppPath = C:\Tools\app.exeboth reduce to\Tools\app.exe, so the real denial on D: disappears from both canonicalcaptureDenialsoutput and the compatibility policy. When both inputs are DOS paths, compare their full paths (including drive); use the volume-relative fallback only when a device-form path prevents that comparison.
volume_relative_path(object_name),
volume_relative_path(app_path),
) {
(Some(object_relative), Some(app_relative)) => {
!object_relative.is_empty() && object_relative.eq_ignore_ascii_case(app_relative)
Comment on lines
+395
to
+396
| let key = normalize_win32_components(&key, !is_verbatim); | ||
| key.to_ascii_lowercase() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📖 Description
Refactors
plm.exeinto a mode-neutral legacy WPR helper that delegates sealed-ETL decoding tolearning_mode_windows::EtlDenialAnalyzer.EvtQuery/EvtRenderanalyzer;denials.jsonoutput and a structured stop result;wpr -stopETL destination with--trace-output;learningModeLogging) and PermissiveLearningMode providers in the embedded WPR profile;The branch is rebased onto
mainafter #759 merged. The rebase had no textual conflicts; semantic compatibility with the merged analyzer was reviewed and corrected before updating this PR.🔗 References
🔍 Validation
cargo test -p plm --all-targets— 133 passed, 1 ignored existing diagnostic-fixture test.wxcaudit stop-argument test.cargo clippy -p plm -p wxc --all-targets -- -D warnings.cargo fmt --all -- --check.git diff --check origin/main...HEAD.✅ Checklist
Cargo.lock, thedependency-feed-checkcheck passes (see docs/pull-requests.md)📋 Issue Type